﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

using System.Data;
using System.Data.SqlClient;
using System.Windows.Forms;

namespace Planning.Classes {
    class SQL {
        #region Construct
        // Stocke que connexion
        private static SqlConnection connexion;
        // Stocke les informations de connexion
        private static string user;
        private static string pwd;
        private static string adr;
        private static string nom;

        public static string e; 

        private SQL() {
            // Valorise les informations de connexion
            SQL.user = Properties.Settings.Default.userBase;
            SQL.pwd = Properties.Settings.Default.pwdBase;
            SQL.adr = Properties.Settings.Default.adrBase;
            SQL.nom = Properties.Settings.Default.nomBase;
            // Tente une connexion
            try {
                SQL.connexion = new SqlConnection("user id=" + SQL.user + "; " + "password=" + SQL.pwd + "; " + "server=" + SQL.adr + "; " + "database=" + SQL.nom + "; " + "connection timeout=30");
            }
            catch (SqlException ex) {
                SQL.e = ex.ToString();
            }
        }

        // Renvoi l'instance de la connexion
        public static SqlConnection getInstance() {
            // Si la connexion n'est pas initialisée
            if (SQL.connexion == null) {
                // Initialise la connexion
                new SQL();
                // Retourne la connexion
                return SQL.connexion;
            }
            // Si la connexion est initialisée
            else {
                // Retourne la connexion
                return SQL.connexion;
            }
        }
        #endregion

        #region fonctions
        // Teste la connexion à la base
        public static bool test() {
            // Récupère la connexion
            SqlConnection con = SQL.getInstance();
            // Essaie d'ouvrir la connexion
            try {
                con.Open();
            }
            // En cas d'erreur, stocke le message, ferme la connexion et retourne faux
            catch (SqlException ex) {
                SQL.e = ex.ToString();
                con.Close();
                return false;
            }
            // Ferme la connexion et retourne vrai
            con.Close();
            return true;
        }

        // Vérifie le couple nom d'utilisateur / mot de passe
        public static bool checkLogin(string username, string password) {
            // Initialise un tableau pour lire les enregistrements
            DataTable retour = new DataTable();
            // Récupère la connexion
            SqlConnection con = SQL.getInstance();
            // Permet de récupérer les erreurs en cas d'incidents
            try {
                // Instancie une commande SQL
                using (SqlCommand cmd = con.CreateCommand()) {
                    // Inscrit la commande
                    cmd.CommandText = "SELECT * FROM CONNEXION WHERE login_connexion = @username AND password_connexion = @password;";
                    // Valorise les paramètres
                    cmd.Parameters.Add("@username", SqlDbType.VarChar, 32).Value = username;
                    cmd.Parameters.Add("@password", SqlDbType.NVarChar, -1).Value = password;
                    // Exécute la commande
                    cmd.Connection.Open();
                    // Stocke le retour de la commande
                    retour.Load(cmd.ExecuteReader());
                }
            }
            // En cas d'erreur [informe], ferme la connexion et retourne faux
            catch (SqlException ex) {
                if (Properties.Settings.Default.erreurSQL) {
                    MessageBox.Show("Erreur de connexion à la base de données. \n\n" + ex, "Erreur !", MessageBoxButtons.OK, MessageBoxIcon.Stop);
                    con.Close();
                    return false;
                }
                else {
                    MessageBox.Show("Erreur de connexion à la base de données.", "Erreur !", MessageBoxButtons.OK, MessageBoxIcon.Stop);
                    con.Close();
                    return false;
                }
            }
            // Ferme la connexion
            con.Close();
            // Si la requête renvoi une ligne
            if (retour.Rows.Count == 1) {
                // retourne vrai
                return true;
            }
            // Sinon retourne faux
            return false;
        }

        // Ajoute une formation
        public static bool ajoutFormation(int lieu, int association, string libelle, string description, int places, DateTime debut, DateTime fin, bool isOuverte) {
            // Récupère la connexion
            SqlConnection con = SQL.getInstance();
            // Permet de récupérer les erreurs en cas d'incidents
            try {
                // Instancie une commande SQL
                using (SqlCommand cmd = con.CreateCommand()) {
                    // Inscrit la commande
                    cmd.CommandText = "INSERT INTO FORMATION (id_lieu, id_association,libelle_formation, description_formation, places_formation, debut_formation, fin_formation, isOuverte) " +
                        "VALUES (@lieu, @association, @libelle, @description, @places, @debut, @fin, @isOuverte);";
                    // Valorise les paramètres
                    cmd.Parameters.Add("@lieu", SqlDbType.Int).Value = lieu;
                    cmd.Parameters.Add("@association", SqlDbType.Int).Value = association;
                    cmd.Parameters.Add("@libelle", SqlDbType.VarChar, 80).Value = libelle;
                    cmd.Parameters.Add("@description", SqlDbType.NVarChar, -1).Value = description;
                    if (places == 0)
                        cmd.Parameters.Add("@places", SqlDbType.Int).Value = DBNull.Value;
                    else
                        cmd.Parameters.Add("@places", SqlDbType.Int).Value = places;
                    cmd.Parameters.Add("@debut", SqlDbType.DateTime).Value = debut;
                    cmd.Parameters.Add("@fin", SqlDbType.DateTime).Value = fin;
                    cmd.Parameters.Add("@isOuverte", SqlDbType.TinyInt).Value = isOuverte;
                    // Exécute la commande
                    cmd.Connection.Open();
                    cmd.ExecuteNonQuery();
                }
            }
            // En cas d'erreur[informe], ferme la connexion et retourne faux
            catch (SqlException ex) {
                if (Properties.Settings.Default.erreurSQL) {
                    MessageBox.Show("Erreur de connexion à la base de données. \n\n" + ex, "Erreur !", MessageBoxButtons.OK, MessageBoxIcon.Stop);
                    con.Close();
                    return false;
                }
                else {
                    MessageBox.Show("Erreur de connexion à la base de données.", "Erreur !", MessageBoxButtons.OK, MessageBoxIcon.Stop);
                    con.Close();
                    return false;
                }
            }
            // Ferme la connexion et retourne vrai
            con.Close();
            return true;
        }
        
        // Modifie une formation
        public static bool modifFormation(int idFormation, int lieu, string libelle, string description, int places, DateTime debut, DateTime fin, bool isOuverte) {
            // Récupère la connexion
            SqlConnection con = SQL.getInstance();
            // Permet de récupérer les erreurs en cas d'incidents
            try {
                // Instancie une commande SQL
                using (SqlCommand cmd = con.CreateCommand()) {
                    // Inscrit la commande
                    cmd.CommandText = "UPDATE FORMATION SET id_lieu = @lieu, libelle_formation = @libelle, description_formation = @description, places_formation = @places, debut_formation = @debut, fin_formation = @fin, isOuverte = @isOuverte WHERE id_formation = @formation;";
                    // Valorise les paramètres
                    cmd.Parameters.Add("@formation", SqlDbType.Int).Value = idFormation;
                    cmd.Parameters.Add("@lieu", SqlDbType.Int).Value = lieu;
                    cmd.Parameters.Add("@libelle", SqlDbType.VarChar, 80).Value = libelle;
                    cmd.Parameters.Add("@description", SqlDbType.NVarChar, -1).Value = description;
                    if (places == 0)
                        cmd.Parameters.Add("@places", SqlDbType.Int).Value = DBNull.Value;
                    else
                        cmd.Parameters.Add("@places", SqlDbType.Int).Value = places;
                    cmd.Parameters.Add("@debut", SqlDbType.DateTime).Value = debut;
                    cmd.Parameters.Add("@fin", SqlDbType.DateTime).Value = fin;
                    cmd.Parameters.Add("@isOuverte", SqlDbType.TinyInt).Value = isOuverte;
                    // Exécute la commande
                    cmd.Connection.Open();
                    cmd.ExecuteNonQuery();
                }
            }
            // En cas d'erreur [informe], ferme la connexion et retourne faux
            catch (SqlException ex) {
                if (Properties.Settings.Default.erreurSQL) {
                    MessageBox.Show("Erreur de connexion à la base de données. \n\n" + ex, "Erreur !", MessageBoxButtons.OK, MessageBoxIcon.Stop);
                    con.Close();
                    return false;
                }
                else {
                    MessageBox.Show("Erreur de connexion à la base de données.", "Erreur !", MessageBoxButtons.OK, MessageBoxIcon.Stop);
                    con.Close();
                    return false;
                }
            }
            // Ferme la connexion et retourne vrai
            con.Close();
            return true;
        }

        // Inscrit un utilisateur à une formation
        public static bool inscriptionFormation(int idAdherent, int idFormation) {
            // Récupère la connexion
            SqlConnection con = SQL.getInstance();
            // Permet de récupérer les erreurs en cas d'incidents
            try {
                // Instancie une commande SQL
                using (SqlCommand cmd = con.CreateCommand()) {
                    // Inscrit la commande
                    cmd.CommandText = "INSERT INTO FORMATION_ADHERENT VALUES(@idAdherent, @idFormation);";
                    // Valorise les paramètres
                    cmd.Parameters.Add("@idAdherent", SqlDbType.Int).Value = idAdherent;
                    cmd.Parameters.Add("@idFormation", SqlDbType.Int).Value = idFormation;
                    // Execute la commande
                    cmd.Connection.Open();
                    cmd.ExecuteNonQuery();                }
            }
            // En cas d'erreur [informe], ferme la connexion et retourne faux
            catch (SqlException ex) {
                if (Properties.Settings.Default.erreurSQL) {
                    MessageBox.Show("Erreur de connexion à la base de données. \n\n" + ex, "Erreur !", MessageBoxButtons.OK, MessageBoxIcon.Stop);
                    con.Close();
                    return false;
                }
                else {
                    MessageBox.Show("Erreur de connexion à la base de données.", "Erreur !", MessageBoxButtons.OK, MessageBoxIcon.Stop);
                    con.Close();
                    return false;
                }
            }
            // Ferme la connexion et retourne vrai
            con.Close();
            return true;
        }

        // Inscrit un utilisateur à une formation
        public static bool desinscriptionFormation(int idAdherent, int idFormation) {
            // Récupère la connexion
            SqlConnection con = SQL.getInstance();
            // Permet de récupérer les erreurs en cas d'incidents
            try {
                // Instancie une commande SQL
                using (SqlCommand cmd = con.CreateCommand()) {
                    // Inscrit la commande
                    cmd.CommandText = "DELETE FROM FORMATION_ADHERENT WHERE id_adherent = @idAdherent AND id_formation = @idFormation;";
                    // Valorise les paramètres
                    cmd.Parameters.Add("@idAdherent", SqlDbType.Int).Value = idAdherent;
                    cmd.Parameters.Add("@idFormation", SqlDbType.Int).Value = idFormation;
                    // Execute la commande
                    cmd.Connection.Open();
                    cmd.ExecuteNonQuery();
                }
            }
            // En cas d'erreur [informe], ferme la connexion et retourne faux
            catch (SqlException ex)
            {
                if (Properties.Settings.Default.erreurSQL)
                {
                    MessageBox.Show("Erreur de connexion à la base de données. \n\n" + ex, "Erreur !", MessageBoxButtons.OK, MessageBoxIcon.Stop);
                    con.Close();
                    return false;
                }
                else
                {
                    MessageBox.Show("Erreur de connexion à la base de données.", "Erreur !", MessageBoxButtons.OK, MessageBoxIcon.Stop);
                    con.Close();
                    return false;
                }
            }
            // Ferme la connexion et retourne vrai
            con.Close();
            return true;
        }

        // Exécute une requête
        public static DataTable requete(string req) {
            // Initialise un tableau qui contiendra le résultat de la requête
            DataTable retour = new DataTable();
            // Récupère la connexion
            SqlConnection con = SQL.getInstance();
            // Permet de récupérer les erreurs en cas d'incidents
            try {
                // Instancie une commande SQL
                using (SqlCommand cmd = SQL.connexion.CreateCommand()) {
                    // Inscrit la commande
                    cmd.CommandText = req;
                    // Exécute la commande
                    cmd.Connection.Open();
                    // Sauvegarde le résultat dans retour
                    retour.Load(cmd.ExecuteReader());
                }
            }
            // En cas d'erreur [informe] et ferme la connexion
            catch (SqlException ex) {
                if (Properties.Settings.Default.erreurSQL) {
                    MessageBox.Show("Erreur de connexion à la base de données. \n\n" + ex, "Erreur !", MessageBoxButtons.OK, MessageBoxIcon.Stop);
                    con.Close();
                }
                else {
                    MessageBox.Show("Erreur de connexion à la base de données.", "Erreur !", MessageBoxButtons.OK, MessageBoxIcon.Stop);
                    con.Close();
                }
            }
            // Ferme la connexion et renvoi le résultat
            con.Close();
            return retour;
        }

        // Exécute une requête sans retour
        public static bool nonQuery(string req) {
            // Récupère la connexion
            SqlConnection con = SQL.getInstance();
            // Permet de récupérer les erreurs en cas d'incidents
            try {
                // Instancie une commande SQL
                using (SqlCommand cmd = SQL.connexion.CreateCommand()) {
                    // Inscrit la commande
                    cmd.CommandText = req;
                    // Exécute la commande
                    cmd.Connection.Open();
                    // Sauvegarde le résultat dans retour
                    cmd.ExecuteNonQuery();
                }
            }
            // En cas d'erreur [informe], ferme la connexion et retourne faux
            catch (SqlException ex) {
                if (Properties.Settings.Default.erreurSQL) {
                    MessageBox.Show("Erreur de connexion à la base de données. \n\n" + ex, "Erreur !", MessageBoxButtons.OK, MessageBoxIcon.Stop);
                    con.Close();
                    return false;
                }
                else {
                    MessageBox.Show("Erreur de connexion à la base de données.", "Erreur !", MessageBoxButtons.OK, MessageBoxIcon.Stop);
                    con.Close();
                    return false;
                }
            }
            // Ferme la connexion et renvoi le résultat
            con.Close();
            return true;
        }
        #endregion
    }
}
